﻿using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Globalization;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Input;
using rgr;
using SQLVis.Vizualizador;
using System.ComponentModel;
using System.Windows.Shapes;

namespace rgr
{
    public class SQLVisTreeMap : RGRTreeMapClass, System.ComponentModel.INotifyPropertyChanged
    {

        public int iZoom= 0;
        private double _cantidadConsultas = 0 ;
        private double _tiempoPromedio = 0;

        public double CantidadConsultas
        {
            get { return _cantidadConsultas; }
            set { _cantidadConsultas = value; OnPropertyChanged("CantidadConsultas"); }
        }

        public bool Loaded
        {
            get { return TreeMapData!=null; }
            
        }

        public SQLVisTreeMap()
        {
            this.AddHandler(UserControl.KeyDownEvent, new RoutedEventHandler(HandleHandledKeyDown), true);
        }

        public SQLVisTreeMapNode FindNodeByPoint(Point MousePos)
        {
            SQLVisTreeMapNode tmn = (SQLVisTreeMapNode)((SQLVisTreeMapNode)TreeMapData).FindNodeByPoint(MousePos);
            return tmn;
        }
        public double TiempoPromedio
        {
            get { return _tiempoPromedio; }
            set { _tiempoPromedio = value; OnPropertyChanged("TiempoPromedio"); }
        }



        

        /// <summary>
        /// Zoom in and out based on the mouse buttons
        /// </summary>
        protected override void MouseDownHandler(object sender, MouseButtonEventArgs e)
        {

                SQLVisTreeMapNode rendered_root = (SQLVisTreeMapNode)TreeMapData;

                if (rendered_root == null)
                {
                    return;
                }

                SQLVisTreeMapNode zr = (SQLVisTreeMapNode)ZoomRoot;

                if (zr != null)
                {
                    rendered_root =(SQLVisTreeMapNode) zr;
                }

                SQLVisTreeMapNode tmn = (SQLVisTreeMapNode) rendered_root.FindNodeByPoint(e.GetPosition(this));

               

                if (tmn != null)
                {
                    //set control focus
                    this.Focus();

                    if (e.LeftButton == MouseButtonState.Pressed)
                    {

                        if (tmn.Level == 2 & iZoom < 2)
                        {
                            iZoom++;
                        }

                        if (iZoom == 2)
                        {
                            string info = tmn.ToString();

                             FormattedText txt = new FormattedText(
                                info,
                                CultureInfo.CurrentCulture,
                                CultureInfo.CurrentCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight,
                                new Typeface("Verdana"),
                                8,
                                Brushes.Black
                            );

                            tmn.FText =txt;
                        }

                        if (tmn != zr)
                        {
                            if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
                            {
                                // Zoom into parent of selected node
                                ZoomRoot = tmn.Parent;
                            }
                            else
                            {
                                // Zoom in one level...
                                while (tmn.Parent != rendered_root)
                                {
                                    tmn = (SQLVisTreeMapNode)tmn.Parent;
                                }
                                ZoomRoot = tmn;
                            }
                        }

                        if (ZoomRoot.TotalChildSize == 0)
                            CantidadConsultas = ZoomRoot.TotalChildSize + 1;
                        else
                            CantidadConsultas = ZoomRoot.TotalChildSize;

                        TiempoPromedio = CalcularTiempoPromedio();//((SQLVisTreeMapNode)ZoomRoot).AverageTime;
                    }
                    else
                    {
                        if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
                        {
                            // un-zoom
                            ZoomRoot = null;
                           
                        }
                        else
                        {
                             if (tmn.Level == 2 && iZoom > 0)
                                iZoom--;

                            FormattedText txt = new FormattedText(
                                tmn.AverageTime + "Seg",
                                CultureInfo.CurrentCulture,
                                CultureInfo.CurrentCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight,
                                new Typeface("Verdana"),
                                6,
                                Brushes.Black
                            );

                            txt.MaxTextWidth = 300;
                            txt.MaxTextHeight = 240;
                            txt.SetFontSize(3, Convert.ToString(tmn.AverageTime).Length, 3);

                            tmn.FText = txt;

                            // pop up one level if no at true node
                            if (zr != null)
                            {
                                ZoomRoot = zr.Parent;
                                if (ZoomRoot != null)
                                {
                                    if (ZoomRoot.TotalChildSize == 0)
                                        CantidadConsultas = ZoomRoot.TotalChildSize + 1;
                                    else
                                        CantidadConsultas = ZoomRoot.TotalChildSize;

                                    TiempoPromedio = CalcularTiempoPromedio();
                                }
                            }
                        }
                    }
                }
            }


        /// <summary>
        /// Compute the text and any adornments for this node
        /// </summary>
        /// <param name="node"></param>
        /// <param name="depth"></param>
        public override void ComputeNodeTextAndAdornments(RGRTreeMapNode node, int depth)
        {
            //
            // The node node, and any node deeper than 2 do not get
            // any text or adornments
            //
            if (depth == 0 || depth > 2)
            {
                node.FText = null;
                node.FTextScaleTransform = null;
                return;
            }

            if (node.FText == null)
            {
                node.FText = new FormattedText(
                    node.Name,
                    CultureInfo.CurrentCulture,
                    CultureInfo.CurrentCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight,
                    TextTypeFace,
                    6,
                    TextBrush
                    );

                if (node.Name.IndexOf("S")!=-1)
                    node.FText.SetFontSize(3, Convert.ToString(((SQLVisTreeMapNode)node).AverageTime).Length, 3);


            }

            if (depth == 1)
            {
                node.FTextOpacity = 0.7;
            }
            else
            {
                node.FTextOpacity = 0.25;
            }

            // Draw the text centered in the node's bounding rectangle
            node.FTextLocation.X = node.BoundingRect.X + (node.BoundingRect.Width - node.FText.Width) / 2;
            node.FTextLocation.Y = node.BoundingRect.Y + (node.BoundingRect.Height - node.FText.Height) / 2;

            // Create a new unfrozen transform
            if (node.FTextScaleTransform == null)
            {
                node.FTextScaleTransform = new ScaleTransform();
            }
            else
            {
                node.FTextScaleTransform = node.FTextScaleTransform.Clone();
            }

            // The transform should scale form the center of the node's bounding rectangle
            node.FTextScaleTransform.CenterX = node.BoundingRect.X + node.BoundingRect.Width / 2;
            node.FTextScaleTransform.CenterY = node.BoundingRect.Y + node.BoundingRect.Height / 2;

            //
            // Make the text fit inside the node's bounding rectangle.  Note, we'll keep the
            // text's aspect ratio the same, scaling to a best fit by X or by Y, but not both
            //

            node.FTextScaleTransform.ScaleX = node.BoundingRect.Width / node.FText.Width;
            node.FTextScaleTransform.ScaleY = node.BoundingRect.Height / node.FText.Height;


            if ((node.FText.Height * node.FTextScaleTransform.ScaleX) > node.BoundingRect.Height)
            {
                node.FTextScaleTransform.ScaleX = node.FTextScaleTransform.ScaleY;
            }
            else
            {
                node.FTextScaleTransform.ScaleY = node.FTextScaleTransform.ScaleX;
            }

            node.FTextScaleTransform.Freeze();
        }

        public void HandleHandledKeyDown(object sender, RoutedEventArgs e)
        {
            KeyEventArgs ke = e as KeyEventArgs;
            if (ke.Key == Key.Space)
            {

                SQLVisTreeMapNode rendered_root = (SQLVisTreeMapNode)TreeMapData;

                if (rendered_root == null)
                {
                    return;
                }

                SQLVisTreeMapNode zr = (SQLVisTreeMapNode)ZoomRoot;

                if (zr != null)
                {
                    rendered_root = (SQLVisTreeMapNode)zr;
                }

                SQLVisTreeMapNode tmn = (SQLVisTreeMapNode)rendered_root.FindNodeByPoint(Mouse.GetPosition(this));

                if (tmn != null)
                {
                    if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
                    {
                        // un-zoom
                        ZoomRoot = null;

                    }
                    else
                    {
                        if (tmn.Level == 2 && iZoom > 0)
                            iZoom--;

                        FormattedText txt = new FormattedText(
                                tmn.AverageTime + "Seg",
                                CultureInfo.CurrentCulture,
                                CultureInfo.CurrentCulture.TextInfo.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight,
                                new Typeface("Verdana"),
                                6,
                                Brushes.Black
                            );

                        //txt.MaxTextWidth = 300;
                        //txt.MaxTextHeight = 240;
                        txt.SetFontSize(3, Convert.ToString(tmn.AverageTime).Length, 3);

                        tmn.FText = txt;

                        // pop up one level if no at true node
                        if (zr != null)
                        {
                            ZoomRoot = zr.Parent;
                            if (ZoomRoot != null)
                            {
                                if (ZoomRoot.TotalChildSize == 0)
                                    CantidadConsultas = ZoomRoot.TotalChildSize + 1;
                                else
                                    CantidadConsultas = ZoomRoot.TotalChildSize;

                                TiempoPromedio = CalcularTiempoPromedio();//((SQLVisTreeMapNode)ZoomRoot).AverageTime;
                            }
                        }
                    } 
                }
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        internal double CalcularTiempoPromedio()
        {
            //Calcular el tiempo promedio de todos los grupos:
            double totalavgTime = 0;
            SQLVisTreeMapNode rendered_root;
            if(ZoomRoot!=null)
                rendered_root = (SQLVisTreeMapNode)ZoomRoot;
            else
                rendered_root = (SQLVisTreeMapNode)TreeMapData;


            if (rendered_root.Children != null)
            {
                foreach (SQLVisTreeMapNode item in rendered_root.Children)
                {
                    if (item.Children != null)
                    { 
                        //volver a iterar sobre los hijos
                        foreach (SQLVisTreeMapNode kid in item.Children)
                        {
                             totalavgTime = totalavgTime + kid.AverageTime;
                        }
                    
                    }
                    else
                        totalavgTime = totalavgTime + item.AverageTime;
                }
            }
            else
            {
                totalavgTime = rendered_root.AverageTime;
            }


            if (rendered_root.TotalChildSize == 0)
                return totalavgTime;
            else
                return totalavgTime / CantidadConsultas;// rendered_root.Children.Length;
        }
    }

    }
